package wh.coach.pivot3.table;

import com.google.common.collect.Lists;
import lombok.NoArgsConstructor;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author xhw
 * @date 2024/2/6
 */

@NoArgsConstructor
public class PivotTableView {

    private final List<String[]> rows = new ArrayList<>();

    public static PivotTableView of(final List<String[]> viewData) {
        PivotTableView pivotTableView = new PivotTableView();
        pivotTableView.rows.addAll(viewData);

        return pivotTableView;
    }

    public void addRow(final Iterable<String> row) {
        Assert.isTrue(rows.size() > 0, "header must be set first");

        final String[] rowAsArray = asArray(row);

        Assert.isTrue(rowAsArray.length == getHeader().length,
                () -> "Row length [%d] is not equal to header length [%d]".formatted(rowAsArray.length, getHeader().length));

        rows.add(rowAsArray);
    }

    @Override
    public boolean equals(final Object obj) {
        if (!(obj instanceof PivotTableView other)) {
            return false;
        }

        final List<String[]> otherRows = other.rows;

        if (rows.size() != otherRows.size()) {
            return false;
        }

        for (int i = 0; i < rows.size(); i++) {
            if (!Arrays.equals(rows.get(i), otherRows.get(i))) {
                return false;
            }
        }

        return true;
    }

    @Override
    public String toString() {
        return rows.stream().map(row -> "\n" + Arrays.toString(row)).collect(Collectors.joining(","));
    }

    private String[] asArray(final Iterable<String> iterable) {
        if (iterable instanceof List) {
            return ((List<String>) iterable).toArray(new String[0]);
        } else {
            return Lists.newArrayList(iterable).toArray(new String[0]);
        }
    }

    private String[] getHeader() {
        return rows.get(0);
    }

    public void setHeader(final Iterable<String> header) {
        String[] headerAsArray = this.asArray(header);

        if (!rows.isEmpty()) {
            rows.clear();
        }

        rows.add(headerAsArray);
    }

}
